package com.mcp.converter.domain.rule.compatibility.function;

import com.mcp.converter.domain.checker.IncompatibilityDetail;
import com.mcp.converter.shared.response.sql.SQLElement;
import com.mcp.converter.domain.rule.compatibility.AbstractFunctionRule;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * 环境/标识符函数兼容性规则
 * OceanBase中不支持Oracle特定的环境和标识符处理函数
 * @author zengxiong
 */
public class EnvironmentIdentifierFunctionRule extends AbstractFunctionRule {

    private static final String RULE_ID = "FN003";
    private static final String RULE_NAME = "环境/标识符函数不兼容";
    private static final String RULE_DESCRIPTION = "OceanBase不支持Oracle特定的环境和标识符处理函数";

    private static final Set<String> ENV_ID_FUNCTIONS = new HashSet<>(Arrays.asList(
        "CVS_RESIDUALS", "RESIDUAL", "SAVE", "SCALE",
        "SELECTIVITY_SIGNATURE", "SYS_OP_C2D", "SYS_OP_C2M", "SYS_OP_C2N",
        "SYS_OP_C2P", "SYS_OP_C2W", "SYS_OP_CKWC", "SYS_OP_CMPVL",
        "SYS_OP_CMPVL2", "SYS_OP_DESC", "SYS_OP_ENCRYPT", "SYS_OP_EXTRACT",
        "SYS_OP_FSL2BM", "SYS_OP_GETHINT", "SYS_OP_HEXTORAW", "SYS_OP_MAKEXML",
        "SYS_OP_MAP_NONNULL", "SYS_OP_NLOG", "SYS_OP_NVL", "SYS_OP_RQSREF",
        "SYS_OP_SEQC", "SYS_OP_TACTION", "SYS_OP_TODATE", "SYS_OP_UNWRAP",
        "SYS_OP_XMLEXISTS", "SYS_OP_XMLGEN", "SYS_OP_XMLTYPE"
    ));

    public EnvironmentIdentifierFunctionRule() {
        super(RULE_ID, RULE_NAME, RULE_DESCRIPTION);
        
        StringBuilder reasonBuilder = new StringBuilder("OceanBase中不支持的环境/标识符处理函数：\n");
        StringBuilder impactBuilder = new StringBuilder("可能导致：\n");
        StringBuilder suggestionBuilder = new StringBuilder("建议：\n");
        
        // 统计与计算函数
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "CVS_RESIDUALS", "残差计算函数不支持",
            "数据分析异常", "在应用层实现残差计算");
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "RESIDUAL", "残差分析函数不支持",
            "统计分析异常", "在应用层实现残差分析");
        
        // 系统操作函数 - 类型转换
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SYS_OP_C2D", "字符到数字转换函数不兼容",
            "类型转换失败", "重构避免使用系统级函数");
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SYS_OP_C2M", "字符到月份转换函数不支持",
            "日期转换失败", "使用标准日期转换函数");
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SYS_OP_C2N", "字符到数值转换函数不支持",
            "数值转换失败", "使用标准数值转换函数");
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SYS_OP_C2P", "字符到路径转换函数不支持",
            "路径处理失败", "在应用层处理路径转换");
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SYS_OP_C2W", "字符到宽字符转换函数不支持",
            "字符编码转换失败", "使用标准字符集转换");
        
        // 系统操作函数 - 比较和检查
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SYS_OP_CKWC", "字符宽度检查函数不支持",
            "字符验证失败", "在应用层实现字符检查");
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SYS_OP_CMPVL", "值比较函数不支持",
            "比较操作异常", "使用标准比较操作符");
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SYS_OP_CMPVL2", "增强值比较函数不支持",
            "比较操作异常", "使用标准比较操作符");
        
        // 系统操作函数 - 加密和安全
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SYS_OP_ENCRYPT", "内部加密算法不支持",
            "数据安全风险", "使用应用层加密方案");
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SYS_OP_HEXTORAW", "十六进制转换函数不支持",
            "数据转换失败", "使用标准进制转换函数");
        
        // 系统操作函数 - 数据处理
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SYS_OP_DESC", "描述符函数不支持",
            "元数据获取失败", "使用系统视图获取元数据");
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SYS_OP_EXTRACT", "数据抽取函数不支持",
            "ETL过程失败", "在应用层实现数据抽取逻辑");
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SYS_OP_FSL2BM", "位图转换函数不支持",
            "位图操作失败", "在应用层实现位图处理");
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SYS_OP_GETHINT", "提示获取函数不支持",
            "查询优化失败", "移除或替换查询提示");
        
        // XML处理函数
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SYS_OP_MAKEXML", "XML构造函数不支持",
            "XML生成失败", "使用专用XML构造库");
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SYS_OP_XMLGEN", "XML生成函数不支持",
            "XML处理失败", "使用专用XML生成库");
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SYS_OP_XMLEXISTS", "XML存在检查函数不支持",
            "XML验证失败", "在应用层实现XML验证");
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SYS_OP_XMLTYPE", "XML类型处理函数不支持",
            "XML类型转换失败", "使用标准XML处理方法");
        
        // 系统操作函数 - 其他
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SYS_OP_MAP_NONNULL", "非空映射函数不支持",
            "空值处理异常", "使用标准空值处理函数");
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SYS_OP_NLOG", "日志函数不支持",
            "日志记录失败", "使用应用层日志系统");
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SYS_OP_NVL", "空值处理函数不支持",
            "空值处理异常", "使用标准NVL函数");
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SYS_OP_RQSREF", "引用处理函数不支持",
            "引用解析失败", "重构避免使用引用");
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SYS_OP_SEQC", "序列处理函数不支持",
            "序列操作失败", "使用标准序列语法");
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SYS_OP_TACTION", "事务操作函数不支持",
            "事务处理异常", "使用标准事务控制语句");
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SYS_OP_TODATE", "日期转换函数不支持",
            "日期转换失败", "使用标准TO_DATE函数");
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SYS_OP_UNWRAP", "解包函数不支持",
            "数据解包失败", "在应用层实现解包逻辑");
        
        // 通用标识符处理
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SAVE", "查询结果保存功能不支持",
            "中间结果丢失", "使用临时表替代保存功能");
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SCALE", "数据缩放函数不支持",
            "数值计算异常", "在应用层实现数据缩放");
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SELECTIVITY_SIGNATURE", "选择性签名函数不支持",
            "查询优化失败", "移除选择性相关函数调用");
        
        setIncompatibilityDetail(
            reasonBuilder.toString(),
            impactBuilder.toString(),
            suggestionBuilder.toString(),
            IncompatibilityDetail.Severity.HIGH
        );
    }
    
    private void addFunctionInfo(StringBuilder reasonBuilder, StringBuilder impactBuilder, StringBuilder suggestionBuilder,
                                 String functionName, String reason, String impact, String suggestion) {
        reasonBuilder.append(" - ").append(functionName).append(": ").append(reason).append("\n");
        impactBuilder.append(" - ").append(functionName).append(": ").append(impact).append("\n");
        suggestionBuilder.append(" - ").append(functionName).append(": ").append(suggestion).append("\n");
    }

    @Override
    public boolean matches(Object target) {
        if (target instanceof SQLElement) {
            SQLElement element = (SQLElement) target;
            if (isFunctionElement(element)) {
                String functionName = element.getName().toUpperCase();
                return ENV_ID_FUNCTIONS.contains(functionName);
            }
        }
        return false;
    }
    
    @Override
    public Set<String> getIncompatibleFunctions() {
        return new HashSet<>(ENV_ID_FUNCTIONS);
    }
}